package nl.hanze.FlitsNieuws.network;

import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.preference.PreferenceManager;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import nl.hanze.FlitsNieuws.Activities.SettingsActivity;
import nl.hanze.FlitsNieuws.Domain.NewsItem;
import nl.hanze.FlitsNieuws.Media.MediaHelper;

/**
 * Deze klasse zorgt voor het posten van een nieuwsitem naar de networkservice.
 * 
 * @author alex
 */
public class NetworkService extends IntentService {

    public static final String ACTION = "action";
    public static final int ACTION_SEND_NEWS_ITEM = 1;
    public static final String RECEIVER = "resultreceiver";
    public static final String NEWS_ITEM = "newsitem";    
    public static final int NETWORK_TIMEOUT = 30 * 1000; // ms
    public static final String DEFAULT_POST_URL = "http://flitsnieuws.maatware.com/flitsnieuws/news/create";
    public static final String PARAM_USERNAME = "username";
    public static final String PARAM_PASSWORD = "password";
    public static final String PARAM_HEADLINE = "headline";
    public static final String PARAM_NEWSTEXT = "newstext";
    public static final String PARAM_STREET = "address";
    public static final String PARAM_CITY = "city";
    public static final String PARAM_LATITUDE = "latitude";
    public static final String PARAM_LONGITUDE = "longitude";
    public static final String PARAM_PICTURE = "image";
    public static final int HTTP_STATUS_OK = 200;
    public static final int HTTP_STATUS_INTERNAL_SERVER_ERROR = 500;
    public static final int HTTP_STATUS_NOT_AUTHORIZED = 403;
    String postAddress;
    private NewsItem item;    
    SharedPreferences prefs;

    public NetworkService() {
        super("NetworkService");        
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        item = intent.getParcelableExtra(NEWS_ITEM);
        ResultReceiver receiver = intent.getParcelableExtra(RECEIVER);
        String postUrlFromSettings = PreferenceManager.getDefaultSharedPreferences(this).getString(SettingsActivity.STRING_POSTADDRESS_PREFERENCE, "");
        postAddress = !postUrlFromSettings.equals("") ? postUrlFromSettings : DEFAULT_POST_URL;
        int result = sendNewsItem(item, intent.getIntExtra(ACTION, 0));
        receiver.send(result, Bundle.EMPTY);
    }

    /**
     * In deze methode wordt de POST request opgebouwd en verzonden naar de networkservice
     * @param item
     * @param action
     * @return
     */
    private int sendNewsItem(NewsItem item, int action) {
        int statusCode = 0;
        HttpURLConnection connection = null;
        DataOutputStream outputStream = null;

        final String lineEnd = "\r\n";
        final String twoHyphens = "--";
        final String boundary = "*****";

        /**
         * Kleine hulpklasse die een name-value paar wegschrijft
         * @author roel
         *
         */
        class ParameterWriter {

            void writeParameter(String name, String value, DataOutputStream outputStream) throws IOException {
                outputStream.writeBytes(lineEnd);
                String pName = name;
                String pValue = value;
                outputStream.writeBytes("Content-Disposition: form-data; name=\"" + pName + "\"");
                outputStream.writeBytes(lineEnd + lineEnd);
                outputStream.writeBytes(pValue);
                outputStream.writeBytes(lineEnd + twoHyphens + boundary);
            }
        }

        int bytesRead;
        byte[] buffer;
        int bufferSize = 1024;

        try {
        	// maak een File object aan dat verwijst naar de afbeelding
            File image = new File(item.getImage());
            // eerst de afbeelding schalen naar een geschikt formaat voor de website
            MediaHelper.resizeBitmap(image);
            // fileInputStream wordt gebruikt om de data van de afbeelding te lezen
            FileInputStream fileInputStream = new FileInputStream(image);
            // haal het doeladres op en maak verbinding
            URL url = new URL(postAddress);
            connection = (HttpURLConnection) url.openConnection();

            // Allow Inputs & Outputs  
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);

            // Enable POST method
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Connection", "Keep-Alive");
            // geef aan dat het een multipart/form-data request is, dit is nodig om een file te kunnen uploaden
            connection.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);
            // maak een outpustStream waarnaar wordt geschreven
            outputStream = new DataOutputStream(connection.getOutputStream());
            //bouw de POST op
            outputStream.writeBytes(twoHyphens + boundary);
            // first write the 'normal' parameters
            ParameterWriter pw = new ParameterWriter();
            pw.writeParameter(PARAM_HEADLINE, item.getHeadLine(), outputStream);
            pw.writeParameter(PARAM_NEWSTEXT, item.getNewsText(), outputStream);
            pw.writeParameter(PARAM_USERNAME, item.getUserName(), outputStream);
            pw.writeParameter(PARAM_PASSWORD, item.getPassWord(), outputStream);
            pw.writeParameter(PARAM_LATITUDE, item.getLattitude(), outputStream);
            pw.writeParameter(PARAM_LONGITUDE, item.getLongitude(), outputStream);
            pw.writeParameter(PARAM_STREET, item.getAddress(), outputStream);
            pw.writeParameter(PARAM_CITY, item.getCity(), outputStream);
            // nu wordt de foto geschreven
            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes("Content-Disposition:form-data;name=\"filename\";filename=\"newsimage.jpg\"" + lineEnd);
            outputStream.writeBytes(lineEnd);
            // maak de buffer
            buffer = new byte[bufferSize];
            // lees de foto
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            while (bytesRead > 0) {
                outputStream.write(buffer, 0, bufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            }
            // sluit foto upload af
            outputStream.writeBytes(lineEnd + twoHyphens + boundary + twoHyphens + lineEnd);
            // haal de html status op van de server
            statusCode = connection.getResponseCode();
            // haal eventueel de status boodschap van de server op
            // String serverResponseMessage = connection.getResponseMessage();
            // sluit alle streams netjes af
            fileInputStream.close();
            outputStream.flush();
            outputStream.close();
        } catch (Exception ex) {
            // Exception handling
            ex.printStackTrace();
        }
        // geef de html statuscode terug
        return statusCode;
    }

}
